using Blockey.ScreenManagers;
using BlockeyEssentials;
using BlockeyEssentials.Input;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;

namespace Blockey
{
    public class BlockeyGame : Game
    {
        public BlockeyGame()
        {
            All.StartGraphicSettings(this);

            All.Just3DTest = true;

            if (All.Just3DTest == false)
            {
                Components.Add(new GamerServicesComponent(this));

                SignedInGamer.SignedIn += new System.EventHandler<SignedInEventArgs>(SignedInGamer_SignedIn);
                SignedInGamer.SignedOut += new System.EventHandler<SignedOutEventArgs>(SignedInGamer_SignedOut);
            }
        }

        #region Main Methods

        protected override void Initialize()
        {
            base.Initialize();
            DebugShapeRenderer.Initialize();
        }

        protected override void LoadContent()
        {
            All.LoadEssentials(this);
            if (All.Just3DTest)
            {
                All.CurrentScreenManager = new GameplayManager3D(this);
                //All.CurrentScreenManager = new CreationManager(this);
            }
            else
            {
                All.CurrentScreenManager = new MenuSystemManager(this);
            }


            Networking.Reset();
        }

        protected override void Update(GameTime gameTime)
        {
            if (Networking.IsRunning)
            {
                Networking.Session.Update();
            }

            Networking.UpdateAsync();

            InputManager.Update();

            if (InputManager.Keyboard.JustPressed(Keys.Escape) || InputManager.GamePad1.JustPressed(Buttons.Back))
                this.Exit();

            All.CurrentScreenManager.Update();

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.SteelBlue);

            var oDSS = DepthStencilState.Default;
            var oBS = BlendState.AlphaBlend;

            GraphicsDevice.DepthStencilState = oDSS;
            GraphicsDevice.BlendState = oBS;

            All.SpriteBatch_Debug.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend);

            All.CurrentScreenManager.Draw();

            DrawNetworkInformation();

            All.SpriteBatch_Debug.End();
            base.Draw(gameTime);
        }

        #endregion

        #region Helper Methods

        private void DrawNetworkInformation()
        {
            if (Networking.IsRunning)
            {
                var oSession = Networking.Session;
                var oVertShift = new Vector2(0, 18);
                var oInfoPosition = new Vector2(50, 50);
                var oBuffer = 20;

                All.SpriteBatch_Debug.Draw(All.Texture_Square,
                    new Rectangle((int)oInfoPosition.X - oBuffer, (int)oInfoPosition.Y - oBuffer, 225, 235),
                    null, Color.DarkSlateGray * 0.5f, 0.0f, Vector2.Zero, SpriteEffects.None, 0.0f);

                All.DrawDebugText("Is Host: " + oSession.IsHost, oInfoPosition, false);

                oInfoPosition += oVertShift;
                All.DrawDebugText("Is Everyone Ready: " + oSession.IsEveryoneReady, oInfoPosition, false);

                oInfoPosition += oVertShift;
                All.DrawDebugText("Total Gamer Count: " + oSession.AllGamers.Count, oInfoPosition, false);

                oInfoPosition += oVertShift;
                All.DrawDebugText("Local Gamer Count: " + oSession.LocalGamers.Count, oInfoPosition, false);

                oInfoPosition += oVertShift;
                All.DrawDebugText("Remote Gamer Count: " + oSession.RemoteGamers.Count, oInfoPosition, false);

                oInfoPosition += oVertShift;
                All.DrawDebugText("Max Gamers: " + oSession.MaxGamers, oInfoPosition, false);

                oInfoPosition += oVertShift;
                All.DrawDebugText("Private Gamer Slots: " + oSession.PrivateGamerSlots, oInfoPosition, false);

                oInfoPosition += oVertShift;
                All.DrawDebugText("Session Type: " + oSession.SessionType, oInfoPosition, false);

                oInfoPosition += oVertShift;
                All.DrawDebugText("Session State: " + oSession.SessionState, oInfoPosition, false);

                oInfoPosition += oVertShift;
                All.DrawDebugText("Bytes/Sec Received: " + oSession.BytesPerSecondReceived, oInfoPosition, false);

                oInfoPosition += oVertShift;
                All.DrawDebugText("Bytes/Sec Sent: " + oSession.BytesPerSecondSent, oInfoPosition, false);

                var oPlayerPosition = new Vector2(50, 350);
                foreach (NetworkGamer oGamer in oSession.AllGamers)
                {
                    All.DrawDebugText(oGamer.Gamertag, oPlayerPosition, true);
                    oPlayerPosition += oVertShift;
                }
            }
            else if (Networking.HasSearchResults)
            {
                var oSelectedSession = Networking.SelectedSession;
                if (oSelectedSession == null)
                    return;

                var oVertShift = new Vector2(0, 18);
                var oInfoPosition = new Vector2(50, 50);

                All.SpriteBatch_Debug.Draw(All.Texture_Square,
                    new Rectangle((int)oInfoPosition.X, (int)oInfoPosition.Y, 300, 400),
                    null, Color.Black, 0.0f, Vector2.Zero, SpriteEffects.None, 0.0f);

                All.DrawDebugText("Host: " + oSelectedSession.HostGamertag, oInfoPosition, false);

                oInfoPosition += oVertShift;
                All.DrawDebugText("Gamers: " + oSelectedSession.CurrentGamerCount, oInfoPosition, false);

                oInfoPosition += oVertShift;
                All.DrawDebugText("Ping: " + oSelectedSession.QualityOfService.AverageRoundtripTime.TotalSeconds, oInfoPosition, false);

                var oAvailableSessions = Networking.AvailableSessions;
                var oSessionPosition = new Vector2(50, 350);
                foreach (var oAvailableSession in oAvailableSessions)
                {
                    All.DrawDebugText(oAvailableSession.HostGamertag, oSessionPosition, true);
                    oSessionPosition += oVertShift;
                }
            }
        }

        #endregion

        #region Event Handlers

        void SignedInGamer_SignedIn(object sender, SignedInEventArgs e)
        {
        }

        void SignedInGamer_SignedOut(object sender, SignedOutEventArgs e)
        {
            All.CurrentScreenManager = new MenuSystemManager(this);
        }

        #endregion

    }
}
